using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using KrasDD.Models;

namespace KrasDD
{
    public static class T4TemplateProcessor
    {
        public static string GenerateSourceCode(METHOD method)
        {
            try
            {
                // 获取模板路径
                var templatePath = GetTemplatePath();
                var templateContent = File.ReadAllText(templatePath);

                // 创建 T4 模板的宿主类
                var templateHost = new MethodTemplateHost
                {
                    Method = method
                };

                // 处理模板
                var processedContent = ProcessTemplate(templateContent, templateHost);

                // 输出生成的源代码用于调试
                Console.WriteLine($"Generated source code for method {method.NAME}:");
                Console.WriteLine("=".PadRight(50, '='));
                Console.WriteLine(processedContent);
                Console.WriteLine("=".PadRight(50, '='));

                return processedContent;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error generating source code for method {method.NAME}: {ex.Message}");
                throw;
            }
        }

        private static string GetTemplatePath()
        {
            var templatePath = Path.Combine(
                AppContext.BaseDirectory,
                "Templates",
                "MethodTemplate.tt"
            );
            
            if (!File.Exists(templatePath))
            {
                throw new FileNotFoundException($"Template file not found: {templatePath}");
            }
            
            return templatePath;
        }

        private static string ProcessTemplate(string templateContent, MethodTemplateHost host)
        {
            // 简化的 T4 模板处理
            // 由于运行时 T4 处理比较复杂，这里我们使用字符串替换的方式
            var result = templateContent;

            // 处理命名空间引用
            result = result.Replace("<#@ template language=\"C#\" #>", "");
            result = result.Replace("<#@ assembly name=\"System.Core\" #>", "");
            result = result.Replace("<#@ assembly name=\"System.Data.Common\" #>", "");
            result = result.Replace("<#@ import namespace=\"System\" #>", "");
            result = result.Replace("<#@ import namespace=\"System.Collections.Generic\" #>", "");
            result = result.Replace("<#@ import namespace=\"System.Linq\" #>", "");
            result = result.Replace("<#@ import namespace=\"System.Text\" #>", "");
            result = result.Replace("<#@ import namespace=\"System.Threading.Tasks\" #>", "");
            result = result.Replace("<#@ import namespace=\"KrasDD.Models\" #>", "");
            result = result.Replace("<#@ import namespace=\"KrasDD.Events\" #>", "");
            result = result.Replace("<#@ import namespace=\"Newtonsoft.Json\" #>", "");
            result = result.Replace("<#@ import namespace=\"Microsoft.Extensions.Caching.Distributed\" #>", "");
            result = result.Replace("<#@ import namespace=\"Microsoft.Extensions.DependencyInjection\" #>", "");

            // 处理类定义部分
            var classStart = result.IndexOf("<#+");
            var classEnd = result.IndexOf("#>");
            
            if (classStart >= 0 && classEnd > classStart)
            {
                // 提取类定义部分
                var classDefinition = result.Substring(classStart + 3, classEnd - classStart - 3);
                
                // 创建模板实例
                var templateInstance = new MethodTemplateHost
                {
                    Method = host.Method
                };

                // 使用反射调用 FormatUserCode 方法
                var formatMethod = typeof(MethodTemplateHost).GetMethod("FormatUserCode", 
                    BindingFlags.NonPublic | BindingFlags.Instance);
                
                if (formatMethod != null)
                {
                    var formattedCode = formatMethod.Invoke(templateInstance, new object[] { host.Method.METHOD_CODE }) as string;
                    
                    // 替换模板中的变量
                    result = result.Substring(classEnd + 2);
                    result = result.Replace("<#= Method.NAME.Replace(\" \", \"_\") #>", 
                        host.Method.NAME.Replace(" ", "_"));
                    result = result.Replace("<#= FormatUserCode(Method.METHOD_CODE) #>", formattedCode);
                    result = result.Replace($"Error in method <#= Method.NAME #>", 
                        $"Error in method {host.Method.NAME}");
                }
            }

            return result;
        }
    }

    // T4 模板宿主类
    public class MethodTemplateHost
    {
        public METHOD Method { get; set; }

        private string FormatUserCode(string methodCode)
        {
            if (string.IsNullOrWhiteSpace(methodCode))
                return string.Empty;
            
            var lines = methodCode.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
            var formattedLines = new List<string>();
            
            foreach (var line in lines)
            {
                var trimmedLine = line.Trim();
                
                if (string.IsNullOrEmpty(trimmedLine))
                {
                    formattedLines.Add("");
                    continue;
                }
                
                // 移除用户代码中的 return 语句（除了 return null;）
                if (trimmedLine.StartsWith("return ") && !trimmedLine.Contains("return null;"))
                {
                    continue;
                }
                
                // 修复常见的语法错误
                trimmedLine = trimmedLine
                    .Replace("DateTime.Now()", "DateTime.Now")
                    .Replace("DateTime.Now( )", "DateTime.Now")
                    .Trim();
                
                // 添加统一的缩进（16个空格）
                formattedLines.Add("                " + trimmedLine);
            }
            
            return string.Join("\n", formattedLines);
        }
    }
}
